package org.Yiran.timetale_re.item.tool.screwdriver.modules;

import org.Yiran.timetale_re.item.ItemsRegister;
import org.Yiran.timetale_re.item.tool.screwdriver.modules.enmu.ModuleCategory;
import org.Yiran.timetale_re.item.tool.screwdriver.modules.enmu.ModuleType;
import org.Yiran.timetale_re.item.tool.screwdriver.modules.items.attribute.BasicMiningModuleItem;
import org.Yiran.timetale_re.item.tool.screwdriver.modules.items.attribute.AdvancedMiningModuleItem;
import org.Yiran.timetale_re.item.tool.screwdriver.modules.items.attribute.EliteMiningModuleItem;
import org.Yiran.timetale_re.item.tool.screwdriver.modules.items.attribute.BasicAttackModuleItem;
import org.Yiran.timetale_re.item.tool.screwdriver.modules.items.attribute.AdvancedAttackModuleItem;
import org.Yiran.timetale_re.item.tool.screwdriver.modules.items.attribute.EliteAttackModuleItem;
import org.Yiran.timetale_re.item.tool.screwdriver.modules.items.function.RedstoneModuleItem;
import org.Yiran.timetale_re.item.tool.screwdriver.modules.items.function.RotationModuleItem;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 模块注册和管理类
 * <p>
 * 管理所有可用的模块
 * </p>
 */
public class Modules {
    
    private static final Map<String, IModule> MODULES = new HashMap<>();
    
    /**
     * 注册模块
     *
     * @param module 模块实例
     * @param <T>    模块类型
     * @return 注册的模块实例
     */
    public static <T extends IModule> T register(T module) {
        validateModuleBeforeRegistration(module);
        MODULES.put(module.getModuleId(), module);
        return module;
    }
    
    /**
     * 注册前验证模块
     * <p>
     * 检查模块及其ID是否有效，如果无效则抛出异常
     * </p>
     *
     * @param module 待注册的模块
     * @throws IllegalArgumentException 当模块或其ID为null或空时抛出
     */
    private static <T extends IModule> void validateModuleBeforeRegistration(T module) {
        if (module == null || module.getModuleId() == null || module.getModuleId().isEmpty()) {
            throw new IllegalArgumentException("Module or its ID cannot be null or empty");
        }
    }
    
    /**
     * 根据ID获取模块
     *
     * @param id 模块ID
     * @return 模块实例的Optional
     */
    public static Optional<IModule> getModule(String id) {
        if (isModuleIdValid(id)) {
            return getModuleById(id);
        } else {
            return Optional.empty();
        }
    }
    
    /**
     * 检查模块ID是否有效
     * <p>
     * 验证模块ID是否不为null且不为空
     * </p>
     *
     * @param id 模块ID
     * @return 如果ID有效返回true，否则返回false
     */
    private static boolean isModuleIdValid(String id) {
        // 检查ID是否有效
        return id != null && !id.isEmpty();
    }
    
    /**
     * 根据ID获取模块
     * <p>
     * 从已注册的模块映射中获取指定ID的模块
     * </p>
     *
     * @param id 模块ID
     * @return 模块实例的Optional
     */
    private static Optional<IModule> getModuleById(String id) {
        return Optional.ofNullable(MODULES.get(id));
    }
    
    /**
     * 获取所有已注册的模块
     *
     * @return 模块映射
     */
    public static Map<String, IModule> getModules() {
        return new HashMap<>(MODULES);
    }
    
    /**
     * 根据模块分类获取模块
     *
     * @param category 模块分类
     * @return 指定分类的模块列表
     */
    public static List<IModule> getModulesByCategory(ModuleCategory category) {
        return MODULES.values().stream()
                .filter(module -> category.equals(module.getModuleCategory()))
                .collect(Collectors.toList());
    }
    
    /**
     * 获取模块按分类分组
     *
     * @return 按分类分组的模块映射
     */
    public static Map<ModuleCategory, List<IModule>> getModulesByCategory() {
        return MODULES.values().stream()
                .collect(Collectors.groupingBy(IModule::getModuleCategory));
    }
    
    /**
     * 初始化所有模块
     * <p>
     * 在模组初始化时调用此方法注册所有模块
     * </p>
     */
    public static void init() {
        registerMiningModules();
        registerAttackModules();
        registerRedstoneModules();
        registerRotationModules();
    }
    
    /**
     * 注册所有挖掘模块
     * <p>
     * 注册基础、中级和高级挖掘模块
     * </p>
     */
    private static void registerMiningModules() {
        // 注册基础挖掘模块
        if (ItemsRegister.BASIC_MINING_MODULE.get() instanceof BasicMiningModuleItem basicMiningModule) {
            register(basicMiningModule);
        }
        
        // 注册中级挖掘模块
        if (ItemsRegister.ADVANCED_MINING_MODULE.get() instanceof AdvancedMiningModuleItem advancedMiningModule) {
            register(advancedMiningModule);
        }
        
        // 注册高级挖掘模块
        if (ItemsRegister.ELITE_MINING_MODULE.get() instanceof EliteMiningModuleItem eliteMiningModule) {
            register(eliteMiningModule);
        }
    }
    
    /**
     * 注册所有攻击模块
     * <p>
     * 注册基础、中级和高级攻击模块
     * </p>
     */
    private static void registerAttackModules() {
        // 注册基础攻击模块
        if (ItemsRegister.BASIC_ATTACK_MODULE.get() instanceof BasicAttackModuleItem basicAttackModule) {
            register(basicAttackModule);
        }
        
        // 注册中级攻击模块
        if (ItemsRegister.ADVANCED_ATTACK_MODULE.get() instanceof AdvancedAttackModuleItem advancedAttackModule) {
            register(advancedAttackModule);
        }
        
        // 注册高级攻击模块
        if (ItemsRegister.ELITE_ATTACK_MODULE.get() instanceof EliteAttackModuleItem eliteAttackModule) {
            register(eliteAttackModule);
        }
    }
    
    /**
     * 注册所有红石模块
     * <p>
     * 注册中级红石模块
     * </p>
     */
    private static void registerRedstoneModules() {
        // 注册中级红石模块
        if (ItemsRegister.REDSTONE_MODULE.get() instanceof RedstoneModuleItem advancedRedstoneModule) {
            register(advancedRedstoneModule);
        }
    }
    
    /**
     * 注册所有朝向模块
     * <p>
     * 注册基础朝向模块
     * </p>
     */
    private static void registerRotationModules() {
        // 注册基础朝向模块
        if (ItemsRegister.ROTATION_MODULE.get() instanceof RotationModuleItem basicRotationModule) {
            register(basicRotationModule);
        }
    }
    
    /**
     * 获取每种模块类型的最高级模块
     *
     * @return 每种模块类型的最高级模块映射
     */
    public static Map<ModuleType, IModule> getHighestLevelModulesByType() {
        Map<ModuleType, IModule> highestLevelModules = new HashMap<>();
        
        // 遍历所有模块，找出每种类型的最高级模块
        processModulesForHighestLevel(highestLevelModules);
        
        return highestLevelModules;
    }
    
    /**
     * 处理模块以找出每种类型的最高级模块
     * <p>
     * 遍历所有已注册的模块，为每种模块类型找出等级最高的模块
     * </p>
     *
     * @param highestLevelModules 存储每种类型最高级模块的映射
     */
    private static void processModulesForHighestLevel(Map<ModuleType, IModule> highestLevelModules) {
        for (IModule module : MODULES.values()) {
            ModuleType moduleType = module.getModuleType();
            if (moduleType != null) {
                updateHighestLevelModule(highestLevelModules, module, moduleType);
            }
        }
    }
    
    /**
     * 更新指定类型的最高级模块
     * <p>
     * 如果当前模块是该类型的第一个模块，或者等级比当前最高级模块更高，则更新映射
     * </p>
     *
     * @param highestLevelModules 存储每种类型最高级模块的映射
     * @param module 当前处理的模块
     * @param moduleType 模块类型
     */
    private static void updateHighestLevelModule(Map<ModuleType, IModule> highestLevelModules, IModule module, ModuleType moduleType) {
        // 如果这是该类型的第一个模块，或者这个模块的等级更高
        IModule currentHighest = highestLevelModules.get(moduleType);
        if (currentHighest == null || getModuleLevel(module) > getModuleLevel(currentHighest)) {
            highestLevelModules.put(moduleType, module);
        }
    }
    
    /**
     * 获取模块等级（数字越大等级越高）
     *
     * @param module 模块
     * @return 模块等级数值
     */
    private static int getModuleLevel(IModule module) {
        return switch (module.getModuleLevel()) {
            case ELITE -> 3;
            case ADVANCED -> 2;
            case BASIC -> 1;
        };
    }
}